home *** CD-ROM | disk | FTP | other *** search
/ Gold Medal Software 3 / Gold Medal Software - Volume 3 (Gold Medal) (1994).iso / graphics / 3dvect30.arj / 3D3.ASM < prev    next >
Assembly Source File  |  1993-11-18  |  26KB  |  880 lines

  1. ;3d vector routines - fast sorting method with tolerenced full sorting (3d1+3d2)
  2. ;
  3. ; - objects can pass through one another and still be sorted correctly
  4. ; - maxsurfs and maxpoints must be large - set to TOTAL points/surfs on screen
  5. ;
  6. ; to use:
  7. ;
  8. ;          call look_at_it         ; make camera look at selected object
  9. ;          call setsincose         ; set rotation multipliers for eye
  10. ;          call show_stars         ; plot background stars
  11. ;          call makeobjs           ; plot all objects in sides table
  12. ;          call instant_mouse      ; plot mouse on screen
  13. ;          call flip_page          ; flip video pages
  14. ;          call clear_fill         ; clear video memory (last screen)
  15. ;          call resetupd           ; reset update for borders
  16. ;          call updvectors         ; move objects around, rotate them
  17.  
  18.            .386p
  19.            jumps
  20.  
  21. code32     segment para public use32
  22.            assume cs:code32, ds:code32
  23.  
  24. ; define externals
  25.  
  26.            extrn objbase:dword     ; object lists and bitmap lists are
  27.            extrn bitbase:dword     ; external! set to 0 if none
  28.            extrn bitx:dword        ; x and y sizes for 3d conversion
  29.            extrn bity:dword
  30.  
  31.            include pmode.inc       ; protected mode externals
  32.            include xmouse.inc      ; xmode mouse externals
  33.            include xmode.inc       ; xmode externals by matt pritchard
  34.            include irq.inc
  35.            include font.inc
  36.  
  37.            include macros.inc
  38.            include equ.inc
  39.  
  40.            include vars3.inc       ; labels and such
  41.            align 16
  42.            include arctan.inc      ; inverse tan
  43.            include sin.inc         ; sin/cosin table
  44.            include shading.inc     ; arctan shading tables
  45.            include math.inc        ; rotate, cos,sin,arctan...
  46.            include xscale.inc
  47.            include poly.inc        ; common ploygon stuff
  48.  
  49.            public makeobjs
  50.            public make1obj
  51.            public flush_surfaces
  52.            public init_tables
  53.  
  54.            strip_bytes equ 8
  55.  
  56.            align 16
  57.  
  58. abort_all:
  59.            add esp,strip_bytes    ; abort from loadpoints and make1obj
  60.            ret                    ; returning now from make1obj call
  61.  
  62.            align 16
  63.  
  64. loadpoints:
  65.            mov bl,userotate[esi]
  66.  
  67.            mov si,whatshape[esi*2] ; get shape, bp = z distance
  68.            mov esi,objbase[esi*4]
  69.            sub esi,4
  70.  
  71. view_is_not_ok:
  72.            add esi,4
  73.            lodsd
  74.  
  75.            cmp eax,zad            ; check if too far to see detail anyway
  76.            jb s view_is_not_ok
  77.  
  78.            lodsd
  79.            add esi,eax
  80. llkk:
  81.            mov ax,[esi]
  82.            mov numpoints,ax
  83.  
  84.            movzx edi,pointindex   ; set xp,yp,zp pointer
  85.  
  86.            add ax,1               ; compensate for center of gravity point
  87.  
  88.            shl ax,1
  89.            add ax,pointindex      ; pointindex = word indexer to last point
  90.            cmp ax,maxpoints*2     ; test for overflow in points tables
  91.            jae abort_all
  92.  
  93.            mov ax,[esi+2]
  94.            mov numsides,ax
  95.  
  96.            add ax,showing
  97.            cmp ax,maxsurfaces-1   ; check for overflow in "sides" tables
  98.            jae abort_all
  99.  
  100.            add esi,4+50           ; skip point and side totals, skip future data
  101.            mov lindex,di          ; set last index to points (this one)
  102.  
  103.            add di,2               ; compensate for center of gravity point
  104. middle_load_points:
  105.            or  bl,bl              ; check userotate command
  106.            jne s np13             ; use different loop if no rotation
  107. np12:
  108.            mov bx,[esi]           ; x
  109.            mov cx,[esi+2]         ; y
  110.            mov bp,[esi+4]         ; z
  111.  
  112.            push edi esi
  113.            call rotate            ; rotate based on object matrix
  114.            add ebp,zad
  115.  
  116.            cmp ebp,ztruncate
  117.            jge s ntrunct
  118.            neg ebp
  119.            cmp ebp,ztruncate
  120.            jge s ntrunct
  121.            mov ebp,ztruncate
  122. ntrunct:
  123.            add ebx,xad
  124.            add ecx,yad
  125.            call make3d
  126.            pop esi edi
  127.            mov xp[edi],bx
  128.            mov yp[edi],cx
  129.            mov zp[edi],bp
  130.            add di,2               ; inc xp indexer
  131.            add esi,6              ; inc input pointer
  132.            dec numpoints
  133.            jne s np12
  134.  
  135.            mov pointindex,di      ; save for next call of loadpoints
  136.  
  137.            ret                    ; esi exits with pointer to sides
  138. np13:
  139.            mov bx,[esi]           ; x
  140.            mov cx,[esi+2]         ; y
  141.            mov bp,[esi+4]         ; z
  142.  
  143.            push edi esi
  144.  
  145.            call rotatenull        ; rotation matrix already set up! (camera)
  146.  
  147.            add ebp,zad
  148.  
  149.            cmp ebp,ztruncate
  150.            jge s ntrunct2
  151.            neg ebp
  152.            cmp ebp,ztruncate
  153.            jge s ntrunct
  154.            mov ebp,ztruncate
  155. ntrunct2:
  156.            add ebx,xad
  157.            add ecx,yad
  158.            call make3d
  159.            pop esi edi
  160.            mov xp[edi],bx
  161.            mov yp[edi],cx
  162.            mov zp[edi],bp
  163.            add di,2               ; inc xp indexer
  164.            add esi,6
  165.            dec numpoints
  166.            jne s np13
  167.  
  168.            mov pointindex,di      ; save for next call of loadpoints
  169.  
  170.            ret
  171.  
  172.            align 16
  173.  
  174. ; handle loading of bitmap from object list
  175.  
  176. ; eg   dw 32,8,5,50,60 ;command is 32,point 8, bitmap 5, x&y scaling of 50,60
  177.  
  178. ld_special:
  179.            lodsw                  ; get from si, first is point
  180.            shl ax,1
  181.            add ax,lindex          ; add to include offset in list
  182.            stosw                  ; put in sides table
  183.  
  184.            mov dx,bp              ; save indexer
  185.            movzx ebp,ax           ; get point indexers
  186.            mov ax,zp[ebp]
  187.            mov zeds[ebx],ax       ; set zed for sort.
  188.            mov bp,dx
  189.  
  190.            movsw                  ; get bitmap type
  191.            movsw                  ; get x then y scaling
  192.            movsw
  193.  
  194.            mov dx,command         ; get command (for iteration bits)
  195.            mov textures[ebx],dx
  196.  
  197.            cmp zad,64000          ; bitmaps farther than 65536 screw up
  198.            jge no_norml           ; you can't see them anyway. prevent overflow
  199.            jmp ln3
  200.  
  201.            align 16
  202.  
  203. loadsides:
  204.            mov edi,offsides       ; get ready for lodsw and stosw
  205.            mov ebp,edi            ; ebp = offset to first point in side
  206.            movzx ebx,showing      ; bx = word indexer for surfaces
  207.            shl bx,1
  208. ld_lp:
  209.            lodsw                  ; get command word
  210.            mov command,ax
  211.  
  212.            test ax,himap          ; if bitmap, do special load,
  213.            jnz ld_special         ; or test previous color
  214.  
  215.            lodsd                  ; get texture data/type
  216.            mov texture12,eax
  217.  
  218.            lodsd                  ; get colour, high byte is other side
  219.            mov colors12,eax
  220.  
  221.            mov cx,lindex          ; quick add for loop
  222.  
  223.            lodsw                  ; get from si, first is unconditinal
  224.            shl ax,1
  225.            add ax,cx              ; add to include offset in list
  226.            stosw                  ; put in di
  227.            mov dx,ax
  228. ld_loop:
  229.            lodsw                  ; get from si
  230.            shl ax,1
  231.            add ax,cx
  232.            stosw                  ; put in di
  233.            cmp ax,dx              ; check all after first point
  234.            je s ld_exitloop
  235.  
  236.            lodsw                  ; get from si
  237.            shl ax,1
  238.            add ax,cx
  239.            stosw                  ; put in di
  240.            cmp ax,dx              ; check all after first point
  241.            je s ld_exitloop
  242.  
  243.            lodsw                  ; get from si
  244.            shl ax,1
  245.            add ax,cx
  246.            stosw                  ; put in di
  247.            cmp ax,dx              ; check all after first point
  248.            jne s ld_loop
  249.  
  250. ld_exitloop:
  251.            push ebp
  252.            push esi
  253.            push ebx
  254.  
  255.            mov edi,ebp            ; adjust bp into appropriate indexer
  256.  
  257.            movzx ebp,w [edi+2]
  258.            mov cx,[zp+ebp]
  259.            mov bp,dx              ; get point indexers
  260.            add cx,[zp+ebp]        ; take average of two z points for sort
  261.            mov zeds[ebx],cx
  262.  
  263.            mov dx,command
  264.  
  265.            test dx,onscr          ; find if test is for on screen pixels
  266.            jnz test_if_on_screen
  267.            test dl,both+point+line ; check if always visible
  268.            jnz its_line
  269.  
  270. return_screen:
  271.            mov bx,[edi+4]
  272.  
  273.            mov dx,[xp+ebp]        ; first point
  274.            mov ax,[yp+ebp]
  275.            mov esq,ax             ; memory
  276.  
  277.            mov bp,[edi+2]
  278.            mov si,[xp+ebp]        ; second point
  279.            mov ax,[yp+ebp]
  280.            mov dsq,ax             ; memory
  281.  
  282.            mov bp,bx
  283.            mov di,[xp+ebp]        ; third point
  284.            mov bp,[yp+ebp]
  285.  
  286.            call checkfront        ; check if side is visable using p1,2,3
  287.  
  288.            pop ebx
  289.            pop esi                ; return object data pointer
  290.            pop ebp                ; return where we are in sides list
  291.  
  292.            mov dx,command
  293.            or  ecx,ecx
  294.            jle s test_shading     ; cx>-1 if side visible, skip if not
  295.            test dx,double         ; test to use other colour
  296.            jz s skipit            ; miss this side...
  297.            shr texture12,16
  298.            shr colors12,16
  299.            xor w texture12,inverse ; do inverse shading xor dx,256
  300. test_shading:
  301.            test texture12,shade+last
  302.            jnz handle_shading     ; shading bit set, do it...
  303. ln2:
  304.            test dx,check          ; find out if side is only a test side
  305.            jnz s no_show
  306.  
  307.            mov ax,w texture12     ; another side added...
  308.            mov textures[ebx],ax
  309.            mov ax,w colors12
  310.            mov surfcolors[ebx],ax
  311. ln3:
  312.            inc showing            ; another side added...
  313.            add bx,2
  314.            add ebp,maxpolys*2     ; bump ebp to next block
  315. no_show:
  316.            test dx,iterate        ; test dx,512
  317.            jnz handle_surface_iteration
  318. skipit:
  319.            test dx,normal         ; do we skip surface normal data
  320.            jz s no_norml
  321.            add esi,6
  322. no_norml:
  323.            test dx,iterate        ; test dx,512
  324.            jnz failed_iteration   ; skip iteration data if surface failure
  325.  
  326. return_iteration:
  327.            mov edi,ebp            ; set di for next stosw
  328.  
  329.            dec numsides           ; count for next side
  330.            jne ld_lp
  331.  
  332.            mov offsides,edi       ; save for next call
  333.  
  334.            ret
  335.            align 16
  336.  
  337. its_line:
  338.            pop ebx esi ebp
  339.            test w texture12,shade+last
  340.            jz s ln2
  341.  
  342. ; handle gourad/lambert shading
  343.  
  344.            align 16
  345. handle_shading:
  346.            test w texture12,last ; test to use previous colour or bitmap call
  347.            jnz ld_do_previous
  348.  
  349.            if usesteel eq yes
  350.            test w texture12,wavey
  351.            jnz ln2
  352.            endif
  353.  
  354.            push ebx esi ebp dx
  355.  
  356.            cmp lamflag,no         ; is lambert matrix set up?
  357.            je s setitup           ; jump to less likely route
  358. return:
  359.            lodsw                  ; get surface normal
  360.            movsx ebx,ax
  361.            lodsw
  362.            movsx ecx,ax
  363.            lodsw
  364.            movsx ebp,ax
  365.  
  366.            call lrotate           ; rotate surface normal by lambert matrix
  367.  
  368.            pop dx
  369.            test w texture12,inverse ; have the sides flipped? test dx,256
  370.            jnz s invert_colour    ; jump to least likely route
  371. lp_contin:
  372.            add edi,256
  373.            shr di,1               ; result -256 to +256, turn into 0-256
  374.            mov al,b shading_tables[edi] ; now into 0-15
  375.            xor ah,ah
  376.  
  377.            pop ebp esi ebx
  378.  
  379.            add w colors12,ax      ; user can have offset color in object!
  380.  
  381.            jmp ln2
  382.  
  383.            align 16
  384. invert_colour:                    ; inversion occures with other side option,
  385.            neg edi                ; always visible option, and shading option
  386.            jmp lp_contin          ; all combined!
  387.  
  388.            align 16
  389. setitup:
  390.            push esi
  391.            mov esi,currobj        ; this is object # from make1obj
  392.            call lambert           ; set up lambert maxtrix
  393.            mov lamflag,yes
  394.            pop esi
  395.            jmp s return
  396.  
  397.            align 16
  398.  
  399. ld_do_previous:
  400.            mov ax,w colors12
  401.            mov cx,surfcolors[ebx-2]
  402.            and cx,00fh            ; drop old colour block, keep shading indexer
  403.            add cx,ax              ; add new colour block
  404.            mov w colors12,cx
  405.  
  406.            jmp ln2
  407.  
  408. ; handle option 512
  409.  
  410.            align 16
  411.  
  412. handle_surface_iteration:
  413.            test dx,normal
  414.            jz s no_norml2
  415.            add esi,6              ; skip if shading normal present
  416. no_norml2:
  417.            lodsw                  ; get number of extra points in iteration
  418.            mov numpoints,ax       ; set as counter
  419.            mov cx,ax              ; save number of extra points for later use
  420.  
  421.            shl ax,1
  422.            add ax,pointindex      ; pointindex = word indexer to last point
  423.            cmp ax,maxpoints*2     ; test for overflow in points tables
  424.            jae abort_all2
  425.  
  426.            lodsw                  ; get number of sides in iteration
  427.            add numsides,ax
  428.  
  429.            add ax,showing
  430.            cmp ax,maxsurfaces-1   ; check for overflow in "sides" tables
  431.            jae abort_all2
  432.  
  433.            add esi,25*2
  434.  
  435.            or  cx,cx              ; no new points to add? (just surfaces)
  436.            je return_iteration
  437.  
  438.            push ebx ebp dx        ; save load and store locations
  439.  
  440.            mov edi,currobj        ; add more points to xp,yp,zp list
  441.            mov bl,userotate[edi]  ; because iteration is visible
  442.  
  443.            mov di,pointindex      ; movzx edi,pointindex
  444.  
  445.            call middle_load_points
  446.            pop dx ebp ebx
  447.  
  448.            jmp return_iteration
  449.  
  450.            align 16
  451.  
  452. abort_all2:
  453.            add esp,strip_bytes    ; abort from iteration and make1obj
  454.            ret                    ; returning now from make1obj call
  455.  
  456. ; perform test for option 1024 - generate iteration if points on screen.
  457. ; routine also tests if polygon crosses screen - eg no point is on the screen
  458. ; but the polygon covers the screen, like the front of a very big building.
  459.  
  460.            align 16
  461.  
  462. test_if_on_screen:
  463.            xor bl,bl              ; bl = quadrant flag
  464.            push dx                ; save command
  465.  
  466.            mov esi,ebp
  467. tios:
  468.            mov cx,xp[esi]         ; cx, dx =(x,y) to test
  469.            mov dx,yp[esi]
  470.  
  471.            mov ah,32              ;  32 16  8    determine where point is,
  472.            cmp cx,xmins           ;1  x  x  x    then or bl with location
  473.            jl s ytest             ;2  x  x  x
  474.            mov ah,8               ;4  x  x  x
  475.            cmp cx,xmaxs           ;
  476.            jge s ytest
  477.            mov ah,16
  478. ytest:
  479.            mov al,1
  480.            cmp dx,ymins
  481.            jl s oritall
  482.            mov al,4
  483.            cmp dx,ymaxs
  484.            jge s oritall
  485.  
  486.            cmp ah,16
  487.            je s on_screen         ; a point is on the screen, generate side...
  488. oritall:
  489.            or bl,ah               ; point is not on the screen, but it may
  490.            or bl,al               ; contribute to a polygon which covers the screen.
  491.  
  492.            add edi,2              ; get next connection for another test
  493.            mov si,sides[edi]
  494.            cmp si,bp              ; test if at last connection in iteration test
  495.            jne tios
  496.  
  497.            xor al,al              ; count number of bits in y (must be >2)
  498.            ror bl,1
  499.            adc al,0
  500.            ror bl,1
  501.            adc al,0
  502.            ror bl,1
  503.            adc al,0
  504.            cmp al,1
  505.            jbe s skipit2
  506.  
  507.            xor al,al              ; now count x (must be >2)
  508.            ror bl,1
  509.            adc al,0
  510.            ror bl,1
  511.            adc al,0
  512.            ror bl,1
  513.            adc al,0
  514.            cmp al,1
  515.            jbe s skipit2
  516. on_screen:
  517.            pop dx
  518.  
  519.            test dx,both           ; side is on screen
  520.            jz return_screen       ; test if alway visible
  521.  
  522.            pop ebx esi ebp        ; always, pop and test for shading
  523.            test dx,shade
  524.            jz ln2                 ; no shading - do normal return
  525.            jmp handle_shading
  526.  
  527. skipit2:
  528.            pop dx ebx esi ebp
  529.            jmp skipit
  530.  
  531. ; handle failure of option 512
  532.  
  533.            align 16
  534.  
  535. failed_iteration:
  536.            add esi,4              ; skip # of points and # of surfaces
  537.            xor ecx,ecx
  538.            lodsw                  ; number of bytes to skip in case of failure
  539.            mov cx,ax
  540.            lodsw                  ; get number of points TOTAL in iteration
  541.            shl ax,1               ; in case iteration in iteration in iteration...
  542.            add pointindex,ax
  543.            add esi,ecx
  544.            jmp return_iteration
  545.  
  546.            align 16
  547.  
  548. ; make object esi, routine assumes object is already ON!  note: esi not si!
  549.  
  550. make1obj:
  551.            mov lamflag,no
  552.            mov currobj,esi
  553.  
  554.            shl si,2               ; si = dword
  555.  
  556.            mov ebx,xs[esi]        ; displacement
  557.            sub ebx,eyex
  558.            mov ecx,ys[esi]
  559.            sub ecx,eyey
  560.            mov ebp,zs[esi]
  561.            sub ebp,eyez
  562.  
  563.            shr ebx,8              ; account for decimal places
  564.            test ebx,00800000h
  565.            jz s pm_1
  566.            or ebx, 0ff000000h
  567. pm_1:
  568.            shr ecx,8
  569.            test ecx,00800000h
  570.            jz s pm_2
  571.            or ecx, 0ff000000h
  572. pm_2:
  573.            shr ebp,8
  574.            test ebp,00800000h
  575.            jz s pm_3
  576.            or ebp, 0ff000000h
  577. pm_3:
  578.            cmp ebx,-maxz          ; check if within visible space
  579.            jl s noa2              ; if object miles away, don't bother
  580.            cmp ebx,maxz
  581.            jg s noa2
  582.  
  583.            cmp ebp,-maxz
  584.            jl s noa2
  585.            cmp ebp,maxz
  586.            jg s noa2
  587.  
  588.            cmp ecx,-maxz
  589.            jl s noa2
  590.            cmp ecx,maxz
  591.            jng s mo_misout
  592.  
  593.            align 4
  594. noa2:
  595.            ret
  596.  
  597. mo_misout:
  598.            call zsolve            ; figure out camera displacement
  599.  
  600.            cmp esi,minz           ; check if behind camera, miminum dist.
  601.            jl s noa2
  602.  
  603.            call xsolve
  604.            mov xad,edi            ; store 3d offsets
  605.            call make3dx           ; now make object farther in 3d
  606.  
  607.            cmp edi,xmit           ; tolerance is max object size/ratio
  608.            jl s noa2
  609.            cmp edi,xmat
  610.            jge s noa2
  611.  
  612.            call ysolve            ; solve y and set correct regs
  613.            mov yad,ecx
  614.            call make3dy           ; now make object farther in 3d
  615.  
  616.            cmp ecx,ymit
  617.            jl s noa2
  618.            cmp ecx,ymat
  619.            jge s noa2
  620.  
  621.            mov zad,ebp
  622.            mov zedthis,bp
  623.            movzx esi,pointindex
  624.  
  625.            mov xp[esi],bx         ; save center of gravity as point 0
  626.            mov yp[esi],cx
  627.            mov zp[esi],bp
  628.  
  629.            mov esi,currobj        ; pop original object number
  630.  
  631.            mov al,userotate[esi]
  632.            test al,himap+point    ; check if bitmap or point
  633.            jnz s mo_special
  634.  
  635.            mov ebx,palxref[esi*4]
  636.            mov palxref,ebx
  637.  
  638.            test al,1+himap+point  ; test to call compound routine
  639.            jnz s mk_skipc         ; skip if anything other than full rotations
  640.            call compound          ; full rotation object, calc. matrix
  641. mk_skipc:
  642.            call loadpoints        ; load points and rotate, exit di=sides
  643.            jmp  loadsides         ; now load sides, starting at di
  644.  
  645.            align 16
  646. noa:
  647.            ret
  648.  
  649.            align 16
  650.  
  651. ; if userotate = 32 then draw bitmap at location x,y,z
  652.  
  653. mo_special:
  654.            cmp pointindex,(maxpoints-1)*2 ; check if there is room in table
  655.            jge s noa
  656.            cmp showing,maxsurfaces-1
  657.            jge s noa
  658.  
  659.            test userotate[esi],point ; is point or bitmap?
  660.            jnz mo_ispoint
  661.  
  662.            cmp ecx,ymit           ; test if bitmap visible
  663.            jl s noa
  664.            cmp ecx,ymat
  665.            jge s noa
  666.  
  667.            cmp ebp,65535          ; far bitmaps screw up, abort
  668.            jge s noa
  669.  
  670.            movzx edi,pointindex
  671.            mov [xp+edi],bx        ; set location of bitmap
  672.            mov [yp+edi],cx
  673.            mov [zp+edi],bp
  674.  
  675.            mov edi,offsides
  676.            add offsides,maxpolys*2 ; update for next object/bitmap
  677.  
  678.            movzx ebx,showing
  679.            shl bp,1               ; adjust so it's the same as loadsides
  680.            mov zeds[ebx*2],bp     ; set z sort indexer
  681.  
  682.            inc showing            ; one more surface...
  683.            xor ah,ah
  684.            mov al,userotate[esi]
  685.            mov textures[ebx*2],ax ; set command for bitmap
  686.  
  687.            mov ax,pointindex
  688.            add pointindex,2
  689.            stosw
  690.            mov ax,whatshape[esi*2]
  691.            stosw
  692.            mov ax,vxs[esi*2]      ; set x and y scales (stretching)
  693.            stosw
  694.            mov ax,vys[esi*2]
  695.            stosw
  696. noa4:
  697.            ret
  698.  
  699.            align 16
  700.  
  701. mo_ispoint:
  702.            cmp bx,xmins            ; draw single point/bullet
  703.            jl s noa4
  704.            cmp bx,xmaxs
  705.            jge s noa4
  706.            cmp cx,ymins
  707.            jl s noa4
  708.            cmp cx,ymaxs            ; ymaxs1 if larger pixel
  709.            jge s noa4
  710.  
  711.            movzx edi,pointindex
  712.            mov [xp+edi],bx         ; set location of point/bitmap
  713.            mov [yp+edi],cx
  714.            mov [zp+edi],bp
  715.  
  716.            mov edi,offsides
  717.            add offsides,maxpolys*2 ; update for next object/bitmap
  718.  
  719.            movzx ebx,showing
  720.            shl bx,1
  721.            mov zeds[ebx],bp       ; set z sort indexer
  722.  
  723.            inc showing            ; one more surface...
  724.  
  725.            mov textures[ebx],64   ; set this command as point
  726.            mov surfcolors[ebx],bulletcolour ; only for variable colours
  727.  
  728.            mov ax,pointindex
  729.            add pointindex,2
  730.  
  731.            stosw
  732.            stosw
  733. noa8:
  734.            ret
  735.  
  736.            align 16
  737.  
  738. set_order:
  739.            movzx ecx,showing
  740.            jcxz s non2_do
  741.            dec ecx
  742.            jz s non2_do
  743.            shl ecx,1
  744.            mov esi,ecx
  745.            add esi,offset order
  746.  
  747.            prc equ 8
  748.  
  749.            cmp cx,prc*2
  750.            jb s ordrloop
  751. bigsloop:
  752.            i=0
  753.            rept prc
  754.            mov [esi+i],cx
  755.            i=i-2
  756.            sub cx,2
  757.            endm
  758.            jz s non2_do
  759.            sub esi,prc*2
  760.            cmp cx,prc*2
  761.            jae s bigsloop
  762. ordrloop:
  763.            mov [esi],cx
  764.            sub esi,2
  765.            dec cx
  766.            loop ordrloop
  767. non2_do:
  768.            mov [order],0          ; fill last
  769.  
  770.            ret
  771.  
  772.            align 16
  773.  
  774. set_makeorder:
  775.  
  776.            i=0
  777.            rept maxobjects        ; macro to produce unrolled loop
  778.            mov makeorder+i*2,i+1  ; set makeorder to 0,1,2,3,4
  779.            i=i+1
  780.            endm
  781.  
  782.            ret
  783.  
  784.            align 16
  785.  
  786. makeobjs:                         ; make all objects, unrolled loop
  787.            mov offsides, offset sides ; clear table indexers for call
  788.            mov pointindex,0
  789.            mov zedthis,0          ; clear temp (last z location)
  790.  
  791.            i=0
  792.  
  793.            rept maxobjects
  794.            local itsoff, dont_flush
  795.  
  796.            mov ax,65535           ; in case of abort
  797.            movzx esi,makeorder+i*2
  798.            test onoff[esi],255    ; check on/off
  799.            jz s itsoff
  800.  
  801.            if i ne 0
  802.  
  803.            mov ax,finalzed+i*2    ; flush buffer if this object far away
  804.            sub ax,zedthis         ; from last.  dont flush if very close.
  805.            add ax,collision/2
  806.            cmp ax,collision
  807.            jae s dont_flush
  808.  
  809.            call flush_surfaces    ; flush previous object
  810.  
  811. dont_flush:
  812.            movzx esi,makeorder+i*2
  813.            endif
  814.  
  815.            call make1obj          ; put new object in buffer
  816.  
  817.            mov ax,zedthis         ; get z and save for re_sort, zedthis = temporary storage
  818. itsoff:
  819.            mov finalzed+i*2,ax
  820.  
  821.            i=i+1
  822.            endm
  823.  
  824.            cmp showing,0          ; if objects have already been flushed, skip
  825.            je miss_flush
  826.            call flush_surfaces
  827. miss_flush:
  828.  
  829. ; bubble sort for entire objects, fastest when already sorted (assumed)
  830.  
  831.            basedif equ offset makeorder - offset finalzed
  832.  
  833. re_sort:
  834.            mov ecx,maxobjects-1
  835.            mov edx,offset finalzed-2
  836.            xor bx,bx              ; sort flag
  837.            xor esi,esi
  838. nextccx:
  839.            add edx,2
  840.            mov esi,maxobjects*2-2+offset finalzed
  841. nextddx:
  842.            sub esi,2
  843.  
  844.            mov ax,[esi+2]
  845.            cmp ax,[esi]
  846.            jle s donotng
  847.            xchg ax,[esi]          ; don't flip entire object, just indexers
  848.            xchg ax,[esi+2]
  849.            mov ax,basedif[esi+2]
  850.            xchg ax,basedif[esi]
  851.            xchg ax,basedif[esi+2]
  852.            inc bx                 ; flag that one sorted
  853. donotng:
  854.            cmp esi,edx
  855.            jnle s nextddx
  856.  
  857.            or  bx,bx              ; re-sort until no more sorts
  858.            loopne s nextccx
  859. quickex:
  860.            ret
  861.  
  862. ; this is called by makeobjs, flushes the surface buffer
  863.  
  864. flush_surfaces:
  865.            call set_order     ; set ordering of sides
  866.            call sort_list     ; sort sides according to z distance
  867.            call drawvect      ; draw 'em on da screen
  868.  
  869.            mov offsides, offset sides ; clear table indexers for call
  870.            mov pointindex,0
  871.  
  872.            ret
  873.  
  874. init_tables:
  875.            call set_makeorder
  876.            ret
  877.  
  878. code32     ends
  879.            end
  880.